package models

import (
	"context"
	"errors"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	"go-chain-api/global"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"log"
	"math/big"
	"strconv"
	"strings"
	"sync"
)

type MongoData struct {
	Id                string `bson:"_id" json:"id"`
	ChainName         string `bson:"chainName" json:"chainName"`
	ChainID           uint   `bson:"chainId" json:"chainID"`
	LatestBlockHeight uint64 `bson:"latestBlockHeight" json:"latestBlockHeight"`
	BlockNumber       uint64 `bson:"blockNumber" json:"blockNumber"`
	BlockHash         string `bson:"blockHash" json:"blockHash"`
	Status            uint64 `bson:"status" json:"status"`
	TransactionHash   string `bson:"transactionHash" json:"txHash"`
	GasUsed           uint64 `bson:"gasUsed" json:"gasUsed"`
	GasPrice          string `bson:"gasPrice" json:"gasPrice"`
	Timestamp         uint64 `bson:"timestamp" json:"timestamp"`
	TransactionFrom   string `bson:"from" json:"from"`
	TransactionTo     string `bson:"to" json:"to"`
	TransactionValue  string `bson:"value" json:"value"`
	Logs              []Log  `bson:"logs" json:"logs"`
	Contract          string `bson:"contract" json:"contract"`
	IsTokenTransfer   uint8  `bson:"isTokenTransfer" json:"isTokenTransfer"` // 0否 1是
	GasLimit          uint64 `bson:"gasLimit" json:"gasLimit"`
	Data              string `bson:"data" json:"data"`
}

type Log struct {
	Address   string   `bson:"address" json:"address"`
	Topics    []string `bson:"topics" json:"topics"`
	Data      string   `bson:"data" json:"data"`
	TokenName string   `bson:"tokenName" json:"tokenName"`
	Decimals  uint8    `bson:"decimals" json:"decimals"`
	SignName  string   `bson:"signName" json:"signName"`
}

type BlockConfig struct {
	ChainName       string `bson:"chainName" json:"chainName"`
	ChainId         uint   `bson:"chainId" json:"chainId"`
	RpcUrl          string `bson:"rpcUrl" json:"rpcUrl"`
	LastBlockNumber uint   `bson:"lastBlockNumber" json:"lastBlockNumber"`
	UsdtAddress     string `json:"usdtAddress"`
}

type TransactionData struct {
	TxHash    string `bson:"txHash" json:"txHash"`
	From      string `bson:"from" json:"from"`
	To        string `bson:"to" json:"to"`
	Timestamp uint64 `bson:"timestamp" json:"timestamp"`
	Amount    string `bson:"amount" json:"amount"`
	GasFee    string `bson:"gasFee" json:"gasFee"`
	Token     string `bson:"token" json:"token"`
}

type MongoDataObject struct {
	Id                int64  `bson:"id" json:"id"`
	ChainName         string `bson:"chainName" json:"chainName"`
	ChainID           uint   `bson:"chainId" json:"chainID"`
	LatestBlockHeight uint64 `bson:"latestBlockHeight" json:"latestBlockHeight"`
	BlockNumber       uint64 `bson:"blockNumber" json:"blockNumber"`
	BlockHash         string `bson:"blockHash" json:"blockHash"`
	Status            uint64 `bson:"status" json:"status"`
	TransactionHash   string `bson:"transactionHash" json:"txHash"`
	GasUsed           uint64 `bson:"gasUsed" json:"gasUsed"`
	GasPrice          string `bson:"gasPrice" json:"gasPrice"`
	Timestamp         uint64 `bson:"timestamp" json:"timestamp"`
	TransactionFrom   string `bson:"from" json:"from"`
	TransactionTo     string `bson:"to" json:"to"`
	TransactionValue  string `bson:"value" json:"value"`
	Logs              Log    `bson:"logs" json:"logs"`
	Contract          string `bson:"contract" json:"contract"`
	IsTokenTransfer   uint8  `bson:"isTokenTransfer" json:"isTokenTransfer"` // 0否 1是
}

//func GetInfoCount() int64 {
//	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
//	documents, err := BlocksClient.CountDocuments(context.Background(), bson.D{})
//	if err != nil {
//		return 0
//	}
//	return documents
//}

// GetTokenRecordByAddress 根据地址获取代币转账记录
func GetTokenRecordByAddress(chainName string, chainId uint, address string, pageIndex uint, pageSize uint) []TransactionData {

	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")

	// 构建聚合管道
	pipeline := mongo.Pipeline{
		{{"$unwind", "$logs"}},
		{{"$match", bson.D{
			{"$and", bson.A{
				bson.D{{"isTokenTransfer", 1}},
				bson.D{{"chainName", chainName}},
				bson.D{{"chainId", chainId}},
				bson.D{{"logs.topics.0", "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"}}},
			},
			{"$or", bson.A{
				bson.D{{"logs.topics.1", address}},
				bson.D{{"logs.topics.2", address}},
			}}},
		}},
		{{"$sort", bson.D{{"_id", -1}}}},
		{{"$skip", pageIndex}},
		{{"$limit", pageSize}},
	}

	// 执行聚合查询
	cursor, err := BlocksClient.Aggregate(context.Background(), pipeline)
	if err != nil {
		log.Fatal(err)
	}

	// 解码结果到结构体数组
	var results []TransactionData
	// 逐个获取结果并构建返回的结果数组
	defer func(cursor *mongo.Cursor, ctx context.Context) {
		err := cursor.Close(ctx)
		if err != nil {

		}
	}(cursor, context.Background())
	for cursor.Next(context.Background()) {
		var result MongoDataObject
		err := cursor.Decode(&result)
		if err != nil {
			log.Print(err)
		}
		var resultData TransactionData
		resultData.TxHash = result.TransactionHash
		resultData.From = common.HexToAddress(result.Logs.Topics[1]).Hex()
		resultData.To = common.HexToAddress(result.Logs.Topics[2]).Hex()
		resultData.Timestamp = result.Timestamp
		resultData.Token = result.Logs.TokenName

		// 创建一个新的big.Int变量并解析十六进制字符串
		num, _ := new(big.Int).SetString(result.Logs.Data, 16)
		// 创建一个表示10^18的big.Int变量
		tenToTheEighteenth := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(result.Logs.Decimals)), nil)
		// 创建一个big.Float来表示num
		numFloat := new(big.Float).SetInt(num)
		// 创建一个表示10^18的big.Float变量
		tenToTheEighteenthFloat := new(big.Float).SetInt(tenToTheEighteenth)
		// 执行除法操作，得到商和余数
		resultData.Amount = new(big.Float).Quo(numFloat, tenToTheEighteenthFloat).Text('f', -1)

		gasUsed := big.NewInt(int64(result.GasUsed))
		gasPrice, _ := new(big.Int).SetString(result.GasPrice, 10)
		mulVal := new(big.Int).Mul(gasUsed, gasPrice)
		mulFloat := new(big.Float).SetInt(mulVal)
		main := new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)
		// 创建一个表示10^18的big.Float变量
		main1 := new(big.Float).SetInt(main)
		resultData.GasFee = new(big.Float).Quo(mulFloat, main1).Text('f', -1)

		results = append(results, resultData)
	}

	if err := cursor.Err(); err != nil {
		log.Fatal(err)
	}
	return results
}

// GetDataByAddressCount 获取代币交易记录总条数
func GetDataByAddressCount(chainName string, chainId uint, address string) int64 {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	// 构建聚合管道
	pipeline := mongo.Pipeline{
		{{"$unwind", "$logs"}},
		{{"$match", bson.D{
			{"$and", bson.A{
				bson.D{{"isTokenTransfer", 1}},
				bson.D{{"chainName", chainName}},
				bson.D{{"chainId", chainId}},
				bson.D{{"logs.topics.0", "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"}}},
			},
			{"$or", bson.A{
				bson.D{{"logs.topics.1", address}},
				bson.D{{"logs.topics.2", address}},
			}}},
		}},
		{{"$count", "total"}},
	}
	// 执行聚合查询
	cursor, err := BlocksClient.Aggregate(context.Background(), pipeline)
	if err != nil {
		log.Fatal(err)
	}

	// 解码结果
	var totalCountResult struct {
		Total int `bson:"total"`
	}
	if cursor.Next(context.Background()) {
		err := cursor.Decode(&totalCountResult)
		if err != nil {
			log.Fatal(err)
		}
		return int64(totalCountResult.Total)
	}

	return 0
}

// GetLatest20 获取最新的20个区块 属性名已小驼峰命名
func GetLatest20(chainName string, chainId uint) []MongoData {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	// 构建聚合管道
	pipeline := mongo.Pipeline{
		{{"$match", bson.D{
			{"$and", bson.A{
				bson.D{{"chainName", chainName}, {"chainId", chainId}}},
			}},
		}},
		{{"$sort", bson.D{{"_id", -1}}}},
		{{"$skip", 0}},
		{{"$limit", 20}},
	}

	// 执行聚合查询
	cursor, err := BlocksClient.Aggregate(context.Background(), pipeline)
	if err != nil {
		log.Fatal(err)
	}

	// 解码结果到结构体数组
	var results []MongoData
	// 逐个获取结果并构建返回的结果数组
	defer func(cursor *mongo.Cursor, ctx context.Context) {
		err := cursor.Close(ctx)
		if err != nil {

		}
	}(cursor, context.Background())

	for cursor.Next(context.Background()) {
		var result MongoData
		if err := cursor.Decode(&result); err != nil {
			log.Fatal(err)
		}
		// 如果上一条的blockNumber和当前的blockNumber相等，跳过
		if len(results) > 0 && results[len(results)-1].BlockNumber == result.BlockNumber {
			continue
		} else {
			results = append(results, result)
		}
	}

	if err := cursor.Err(); err != nil {
		log.Fatal(err)
	}
	return results
}

// GetBlockInfoByName 根据区块号获取详情
func GetBlockInfoByName(chainName string, chainId uint) (BlockConfig, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("scan_config")
	var block BlockConfig
	filter := bson.D{{"chainName", chainName}, {"chainId", chainId}}
	err := BlocksClient.FindOne(context.Background(), filter).Decode(&block)
	return block, err
}

func GetInfoInfoByName(chainName string, mainCoinType int64) (BlockConfig, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("scan_config")
	var block BlockConfig
	filter := bson.D{{"chainName", chainName}, {"udunId", mainCoinType}}
	err := BlocksClient.FindOne(context.Background(), filter).Decode(&block)
	return block, err
}

// GetTransactionByHash 根据交易hash获取交易详情
func GetTransactionByHash(chainName string, txHash string) (MongoData, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	var block MongoData
	filter := bson.D{{"chainName", chainName}, {"transactionHash", txHash}}
	err := BlocksClient.FindOne(context.Background(), filter).Decode(&block)
	return block, err
}

// GetTransactionRecords 获取交易记录
func GetTransactionRecords(chainName string, pageIndex uint, pageSize uint) (int64, []MongoData, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")

	filter := bson.D{
		{"chainName", chainName},
	}
	findOptions := options.Find()
	findOptions.SetSort(bson.D{{"_id", -1}})
	findOptions.SetSkip(int64(pageIndex))
	findOptions.SetLimit(int64(pageSize))

	// 查询总数
	count, err := BlocksClient.CountDocuments(context.Background(), filter, nil)
	if err != nil {
		return 0, []MongoData{}, err
	}
	find, err := BlocksClient.Find(context.Background(), filter, findOptions)
	if err != nil {
		return 0, []MongoData{}, err
	}

	var results []MongoData

	for find.Next(context.Background()) {
		var result MongoData
		if err := find.Decode(&result); err != nil {
			return 0, []MongoData{}, err
		}
		results = append(results, result)
	}

	return count, results, nil
}

// GetTransactionByAddress 根据地址获取交易记录
func GetTransactionByAddress(chainName string, chainId uint, address string, pageIndex uint, pageSize uint) (int64, []MongoData, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	address = common.HexToAddress(address).Hex()
	filter := bson.M{
		"chainName": chainName,
		"chainId":   chainId,
		"$or": []bson.M{
			{"from": address},
			{"to": address},
			{"contract": address},
		},
	}

	findOptions := options.Find()
	findOptions.SetSort(bson.D{{"_id", -1}})
	findOptions.SetSkip(int64(pageIndex))
	findOptions.SetLimit(int64(pageSize))

	// 查询总数
	count, err := BlocksClient.CountDocuments(context.Background(), filter, nil)
	if err != nil {
		return 0, []MongoData{}, err
	}
	find, err := BlocksClient.Find(context.Background(), filter, findOptions)
	if err != nil {
		return 0, []MongoData{}, err
	}

	var results []MongoData

	for find.Next(context.Background()) {
		var result MongoData
		if err := find.Decode(&result); err != nil {
			return 0, []MongoData{}, err
		}
		results = append(results, result)
	}

	return count, results, nil
}

// GetTokenHoldersCount 根据代币地址获取持有者数量
func GetTokenHoldersCount(chainName string, chainId uint, tokenAddress string) (int64, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	//pipeline := mongo.Pipeline{
	//	{{"$match", bson.D{{"isTokenTransfer", 1}, {"chainName", chainName}, {"chainId", chainId}, {"contract", tokenAddress}}}},
	//	{{"$group", bson.D{{"_id", "$from"}}}},
	//}
	//
	//// 执行聚合查询
	//cursor, err := BlocksClient.Aggregate(context.TODO(), pipeline)
	//if err != nil {
	//	return 0, err
	//}
	//defer func(cursor *mongo.Cursor, ctx context.Context) {
	//	err := cursor.Close(ctx)
	//	if err != nil {
	//		log.Println("GetTokenHoldersCount：", err)
	//	}
	//}(cursor, context.TODO())
	//
	//// 解析结果
	//var results []bson.M
	//if err = cursor.All(context.TODO(), &results); err != nil {
	//	return 0, err
	//}

	var blockList []*MongoData
	filter := bson.D{{"isTokenTransfer", 1}, {"chainName", chainName}, {"chainId", chainId}, {"contract", tokenAddress}}
	find, err := BlocksClient.Find(context.TODO(), filter)
	if err != nil {
		return 0, err
	}
	err = find.All(context.TODO(), &blockList)
	if err != nil {
		return 0, err
	}
	var dataList []string
	for _, data := range blockList {
		for _, l := range data.Logs {
			if l.Topics[0] == "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" {
				dataList = append(dataList, l.Topics[1], l.Topics[2])
			}
		}
	}
	unique := make(map[string]bool)
	for _, value := range dataList {
		unique[value] = true
	}
	return int64(len(unique)), nil
}

// GetTokenTxCount 根据代币地址获取交易总数
func GetTokenTxCount(chainName string, tokenAddress string) (int64, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")

	filter := bson.D{{"isTokenTransfer", 1}, {"chainName", chainName}, {"contract", tokenAddress}}

	// 查询总数
	count, err := BlocksClient.CountDocuments(context.Background(), filter, nil)
	if err != nil {
		return 0, err
	}

	return count, nil
}

// GetTokenTransferAmount 根据代币地址获取交易总数
func GetTokenTransferAmount(chainName string, tokenAddress string) (int64, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")

	filter := bson.D{{"isTokenTransfer", 1}, {"chainName", chainName}, {"contract", tokenAddress}}

	// 查询全部数据
	cursor, err := BlocksClient.Find(context.Background(), filter)
	if err != nil {
		return 0, err
	}

	defer func(cursor *mongo.Cursor, ctx context.Context) {
		err := cursor.Close(ctx)
		if err != nil {
			log.Println("GetTokenTransferAmount：", err)
		}
	}(cursor, context.Background())
	// 查询代币精度
	token := &TokenInfo{}
	tokenInfo := token.GetTokenInfoByAddress(tokenAddress)
	// 解析结果
	count := int64(0)
	index := 0
	log.Println("开始计算")
	// 循环
	for cursor.Next(context.Background()) {
		var result MongoData
		if err := cursor.Decode(&result); err != nil {
			return 0, err
		}
		for _, item := range result.Logs {
			// 使用big.Int来解析十六进制字符串表示的大整数
			amount := new(big.Int)
			_, success := amount.SetString(item.Data, 16)
			if !success {
				return 0, errors.New("failed to set string")
			}
			// 计算精度
			amount.Mul(amount, new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(tokenInfo.Decimals)), nil))
			// 计算总数
			count += amount.Int64()
			index++
		}
	}
	log.Println("count:", count, "index:", index)
	log.Println("结束计算")
	return count, nil
}

// GetMinerFee 获取最小旷工费
func GetMinerFee(chainName string) (string, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")

	filter := bson.D{{"chainName", chainName}, {"gasUsed", bson.D{{"$gt", 0}}}}
	findOptions := options.FindOne()
	findOptions.SetSort(bson.D{{"gasUsed", 1}})

	one := BlocksClient.FindOne(context.Background(), filter, findOptions)

	var result MongoData

	err := one.Decode(&result)
	if err != nil {
		return "0", err
	}

	gasPriceRat := new(big.Rat)
	gasPriceRat.SetString(result.GasPrice)
	gasUsedRat := new(big.Rat).SetInt64(int64(result.GasUsed))
	divider := new(big.Rat).SetInt64(1000000000000000000)

	resultRat := new(big.Rat).Mul(gasPriceRat, gasUsedRat)
	resultRat.Quo(resultRat, divider)
	resultString := resultRat.FloatString(18)
	return resultString, nil
}

// GetFeeTotal 获取全部矿工费
func GetFeeTotal(chainName string) (string, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")

	filter := bson.D{{"chainName", chainName}}
	cursor, err := BlocksClient.Find(context.Background(), filter)
	if err != nil {
		log.Fatal(err)
	}
	defer func(cursor *mongo.Cursor, ctx context.Context) {
		err := cursor.Close(ctx)
		if err != nil {
			log.Println("GetFeeTotal：", err)
		}
	}(cursor, context.Background())

	totalFee := new(big.Rat)

	for cursor.Next(context.Background()) {
		var result MongoData
		if err := cursor.Decode(&result); err != nil {
			log.Fatal(err)
		}

		gasPriceRat := new(big.Rat)
		gasPriceRat.SetString(result.GasPrice)
		gasUsedRat := new(big.Rat).SetInt64(int64(result.GasUsed))
		divider := new(big.Rat).SetInt64(1000000000000000000)

		resultRat := new(big.Rat).Mul(gasPriceRat, gasUsedRat)
		resultRat.Quo(resultRat, divider)
		totalFee.Add(totalFee, resultRat)
	}

	return totalFee.FloatString(18), nil
}

func IsContractAddress(rpcUrl string, address string) (bool, error) {
	client, err := ethclient.Dial(rpcUrl)
	if err != nil {
		return false, err
	}
	defer client.Close()
	addr := common.HexToAddress(address)
	code, err := client.CodeAt(context.Background(), addr, nil) // 获取地址对应的合约代码
	if err != nil {
		return false, err
	}
	return len(code) > 0, nil // 如果合约代码长度大于0，则说明是合约地址
}

func GetTxHashByAddress(chainName string, chainId uint, address string, pageIndex uint, pageSize uint) ([]MongoData, error) {
	BlocksClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	address = common.HexToAddress(address).Hex()
	filter := bson.M{
		"chainName": chainName,
		"chainId":   chainId,
		"$or": []bson.M{
			{"from": address},
			{"to": address},
			{"contract": address},
		},
	}

	findOptions := options.Find()
	findOptions.SetSort(bson.D{{"_id", -1}})
	findOptions.SetSkip(int64(pageIndex))
	findOptions.SetLimit(int64(pageSize))

	find, err := BlocksClient.Find(context.Background(), filter, findOptions)
	if err != nil {
		return nil, err
	}

	var results []MongoData

	for find.Next(context.Background()) {
		var result MongoData
		if err := find.Decode(&result); err != nil {
			return nil, err
		}
		results = append(results, result)
	}

	return results, nil
}

func ParseAmount(decimal uint, amount string) string {
	divisor := big.NewInt(10).Exp(big.NewInt(10), big.NewInt(int64(decimal)), nil)
	dividendBig, _ := new(big.Int).SetString(amount, 10)
	expression := new(big.Rat).SetInt(dividendBig).Quo(new(big.Rat).SetInt(dividendBig), new(big.Rat).SetInt(divisor))
	resultFloat, _ := expression.Float64()
	quotient := strconv.FormatFloat(resultFloat, 'f', -1, 64)
	return quotient
}

func GetRecordByAddressAndContract(chainName string, chainId uint, address string, contract string, page uint, pageSize uint, decimal uint) ([]TransactionData, error) {
	collection := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	filter := bson.M{
		"isTokenTransfer": 1,
		"chainName":       chainName,
		"chainId":         chainId,
	}

	// 定义排序条件和分页
	sort := bson.M{"timestamp": -1}
	findOptions := options.Find()
	findOptions.SetSort(sort)
	findOptions.SetProjection(bson.M{"logs": 1, "transactionHash": 1, "gasPrice": 1, "gasUsed": 1, "timestamp": 1})

	cursor, err := collection.Find(context.TODO(), filter, findOptions)
	if err != nil {
		return nil, err
	}
	defer cursor.Close(context.TODO())

	skip := int64(page)
	limit := int64(pageSize)
	count := int64(0)
	var wg sync.WaitGroup
	results := make(chan TransactionData, pageSize) // 使用 channel 收集结果
	tempAddress := "0x000000000000000000000000" + common.HexToAddress(address).Hex()[2:]
	contractHex := common.HexToAddress(contract).Hex()
	topic0 := "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"

	for cursor.Next(context.TODO()) {
		var result MongoData
		if err := cursor.Decode(&result); err != nil {
			return nil, err
		}

		for _, l := range result.Logs {
			if count >= skip && count < skip+limit {
				if l.Address == contractHex && l.Topics[0] == topic0 {
					if l.Topics[1] == strings.ToLower(tempAddress) || l.Topics[2] == strings.ToLower(tempAddress) {
						wg.Add(1) // 增加 WaitGroup 计数
						go func(result MongoData, l Log) {
							defer wg.Done() // 完成时减少计数
							gasPrice, _ := strconv.ParseUint(result.GasPrice, 10, 64)
							var tx TransactionData
							tx.TxHash = result.TransactionHash
							tx.From = common.HexToAddress(l.Topics[1]).Hex()
							tx.To = common.HexToAddress(l.Topics[2]).Hex()
							tx.GasFee = strconv.FormatUint(result.GasUsed*gasPrice, 10)
							tx.Timestamp = result.Timestamp

							// 处理精度
							decimalValue := new(big.Int)
							decimalValue.SetString(l.Data, 16)
							tenTo18 := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(decimal)), nil)
							resultFloat := new(big.Float).Quo(new(big.Float).SetInt(decimalValue), new(big.Float).SetInt(tenTo18))
							tx.Amount = resultFloat.Text('f', -1)

							count++
							results <- tx // 将结果发送到 channel
						}(result, l) // 传递当前的 result 和 l
					}
				}
			}
		}
	}

	if err := cursor.Err(); err != nil {
		return nil, err
	}

	wg.Wait()      // 等待所有 goroutines 完成
	close(results) // 关闭 channel

	var finalResults []TransactionData
	for tx := range results {
		finalResults = append(finalResults, tx) // 收集结果
	}

	return finalResults, nil
}

func GetMainRecordByAddress(chainName string, chainId uint, address string, page uint, pageSize uint) ([]TransactionData, error) {
	collection := global.DBEngine.Database(global.DbConfig.DbName).Collection("block_transaction_info")
	filter := bson.M{
		"chainName": chainName,
		"chainId":   chainId,
		"$or": []bson.M{
			{"from": common.HexToAddress(address).Hex()},
			{"to": common.HexToAddress(address).Hex()},
		},
		"value": bson.M{"$ne": "0"}, // 确保 value 不等于 "0"
	}

	// 定义排序条件
	sort := bson.M{"timestamp": -1} // -1 表示降序，1 表示升序
	findOptions := options.Find()
	findOptions.SetSort(sort)

	cursor, err := collection.Find(context.TODO(), filter, findOptions)
	if err != nil {
		return []TransactionData{}, err
	}
	skip := int64(page)
	limit := int64(pageSize)
	count := int64(0)
	var results []TransactionData
	for cursor.Next(context.TODO()) {
		var result MongoData
		if err := cursor.Decode(&result); err != nil {
			return []TransactionData{}, err
		}
		if count >= skip && count < skip+limit {
			gasPrice, _ := strconv.ParseUint(result.GasPrice, 10, 64)
			var tx TransactionData
			tx.TxHash = result.TransactionHash
			tx.From = result.TransactionFrom
			tx.To = result.TransactionTo
			tx.GasFee = strconv.FormatUint(result.GasUsed*gasPrice, 10)
			tx.Timestamp = result.Timestamp
			tx.Token = ""
			// 处理精度- 开始
			decimalValue := new(big.Int)
			decimalValue.SetString(result.TransactionValue, 10)
			tenTo18 := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(18)), nil)
			result := new(big.Float).Quo(new(big.Float).SetInt(decimalValue), new(big.Float).SetInt(tenTo18))
			resultStr := result.Text('f', -1)
			// 处理精度- 完成
			tx.Amount = resultStr

			results = append(results, tx)
		}
		count++
	}

	if err := cursor.Err(); err != nil {
		return []TransactionData{}, err
	}

	if err := cursor.Close(context.TODO()); err != nil {
		return []TransactionData{}, err
	}

	return results, nil
}
